﻿/*  ------------------------------------------------------------------------
	NQ Common Services Library
	
	Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
   
	The Original Code is code of NQ Common Services Library.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2006-2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	Alternatively, the contents of this file may be used under the terms
	of the GNU General Public License Version 2.0 or later (the "GPL"),
	or the GNU Lesser General Public License Version 2.1 or later (the
	"LGPL"), in which case the provisions of the GPL or the LGPL are
	applicable instead of those above. If you wish to allow use of your
	version of this file only under the terms of the GPL or the LGPL and
	not to allow others to use your version of this file under the MPL,
	indicate your decision by deleting the provisions above and replace
	them with the notice and other provisions required by the GPL or the
	LGPL. If you do not delete the provisions above, a recipient may use
	your version of this file under the terms of any of the MPL, the GPL
	or the LGPL.
	------------------------------------------------------------------------
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AWZhome.NQ.Core;
using AWZhome.NQ.Core.Fluent;
using Microsoft.Win32;
using System.IO;

namespace AWZhome.NQ.CommonServices
{
	[NQExportedService]
	[NQServiceAttachment(CommonAttachLists.MainContainer_Startup)]
	internal class FileGUIManagerService
	{
		private IContainer _containerService;
		private INQFileGUIHandler[] _handlers;
		private Dictionary<string, INQFileGUIDescriptor> _descriptors = new Dictionary<string, INQFileGUIDescriptor>();

		private string _lastDir;
		private int _lastFilterIndex = 1;

		public FileGUIManagerService(IContainer parent)
		{
			_containerService = parent;

			// Create file handlers
			_handlers = ServiceCore
				.RetrieveAttached<INQFileGUIHandler>(CommonAttachLists.FileGUIManager_Handlers)
				.To;

			if (_handlers != null)
			{
				// Create menu items
				IBarManager servBar = _containerService.BarService;
				servBar.ItemClicked += servBar_ItemClicked;

				INQResourceGUIManager servRes = ServiceCore
					.Get<Services.IResourceGUIService>()
					.To;
				Dictionary<string, string> groups = new Dictionary<string, string>();
				IBarItem newFileItem = servBar.GetItem("mnuFile.New");
				IBarItem newFileToolItem = servBar.GetItem("tlbMain.New");

				foreach (INQFileGUIHandler handler in _handlers)
				{
					foreach (INQFileGUIDescriptor desc in handler.FileDescriptors)
					{
						// Create group item
						IBarItem groupItem;
						IBarItem groupToolItem;

						string itemID = NQServiceManager.Instance.GetServiceInfoFromObject(handler).ServiceInterface.FullName + "."
							+ desc.Description.ToLower().Replace(' ', '_');
						try
						{
							if (!groups.ContainsKey(desc.Group.ToLower()))
							{
								groups.Add(desc.Group.ToLower(), desc.Group.ToLower().Replace(' ', '_'));
								groupItem = servBar.CreateItem("mnuFile.New.filegroup." + groups[desc.Group.ToLower()], BarItemType.MenuItem);
								groupToolItem = servBar.CreateItem("tlbMain.New.filegroup." + groups[desc.Group.ToLower()], BarItemType.MenuItem);
								groupItem.ItemText = desc.Group;
								groupToolItem.ItemText = desc.Group;
							}
							else
							{
								groupItem = servBar.GetItem("mnuFile.New.filegroup." + groups[desc.Group.ToLower()]);
								groupToolItem = servBar.GetItem("tlbMain.New.filegroup." + groups[desc.Group.ToLower()]);
							}

							// Create menu item for file descriptor
							IBarItem descItem = servBar.CreateItem("mnuFile.New.filedesc." + itemID, BarItemType.MenuItem);
							IBarItem descToolItem = servBar.CreateItem("tlbMain.New.filedesc." + itemID, BarItemType.MenuItem);
							descItem.ItemText = desc.Description;
							descToolItem.ItemText = desc.Description;
							if (!String.IsNullOrEmpty(desc.IconResComponent) && !String.IsNullOrEmpty(desc.IconResName))
							{
								descItem.ItemImage = servRes.GetResImageSource(desc.IconResComponent, desc.IconResName);
								descToolItem.ItemImage = servRes.GetResImageSource(desc.IconResComponent, desc.IconResName);
							}

							// Save descriptor reference in hashmap
							_descriptors.Add(itemID, desc);

							// Add the items to existing menu structure
							newFileItem.AddItem("mnuFile.New.filegroup." + groups[desc.Group.ToLower()]);
							newFileToolItem.AddItem("tlbMain.New.filegroup." + groups[desc.Group.ToLower()]);
							groupItem.AddItem("mnuFile.New.filedesc." + itemID);
							groupToolItem.AddItem("tlbMain.New.filedesc." + itemID);
						}
						catch (BarDefinitionException ex)
						{
							ServiceCore.Log.From(this).Error(ex);
						}
					}
				}
			}
		}

		#region Private methods

		private void servBar_ItemClicked(object sender, BarItemClickedEventArgs e)
		{
			if (_descriptors.Count > 0)
			{
				if ((e.Item.ItemKey.StartsWith("mnuFile.New.filedesc.")) || (e.Item.ItemKey.StartsWith("tlbMain.New.filedesc.")))
				{
					// Hint: "mnuFile.New.filedesc" and "tlbMain.New.filedesc." have the same length!
					string itemID = e.Item.ItemKey.Substring("mnuFile.New.filedesc.".Length);

					INQFileGUIDescriptor descriptor = _descriptors[itemID];
					// The service name is the first part of the itemID
					INQFileGUIHandler handler = null;
					try
					{
						handler = (from h in _handlers
								   where itemID.StartsWith(NQServiceManager.Instance.GetServiceInfoFromObject(h).ServiceInterface.FullName)
								   select h).SingleOrDefault();

						// Call handler method
						if (handler != null)
						{
							handler.NewFileSelected(_containerService, descriptor);
						}
					}
					catch (Exception)
					{
						// We have to ignore exceptions thrown by SingleOrDefault() method
					}
				}
				else if ((e.Item.ItemKey == "mnuFile.Open") || (e.Item.ItemKey == "tlbMain.Open"))
				{
					// Fill filter list
					List<string> filters = new List<string>();
					List<INQFileGUIDescriptor> filterdesc = new List<INQFileGUIDescriptor>();
					foreach (INQFileGUIDescriptor filedesc in _descriptors.Values)
					{
						// Saving the file descriptor objects with the same index as the filter
						filterdesc.Add(filedesc);
						filters.Add(filedesc.FilterName + " (" + filedesc.Mask.ToLower() + ")|" + filedesc.Mask.ToLower() + "|");
					}

					// Show open file dialog
					OpenFileDialog fileDlg = new OpenFileDialog();

					fileDlg.InitialDirectory = _lastDir;
					fileDlg.Multiselect = true;

					// Setting the filters
					string fileFilter = "";
					foreach (string filter in filters)
					{
						fileFilter += filter;
					}

					fileDlg.Filter = fileFilter.Substring(0, fileFilter.Length - 1);
					fileDlg.FilterIndex = _lastFilterIndex;

					if ((bool) fileDlg.ShowDialog())
					{
						// Save selected filter for the next time
						_lastFilterIndex = fileDlg.FilterIndex;

						// A file has been selected, get the descriptor from selected filter
						INQFileGUIDescriptor descriptor = filterdesc[fileDlg.FilterIndex - 1];
						INQFileGUIHandler handler = null;
						try
						{
							// Look for the handler service where the descriptor is defined at
							handler = (from h in _handlers
									   where h.FileDescriptors.Contains(descriptor)
									   select h).SingleOrDefault();

							// Call handler method
							if (handler != null)
							{
								// Call method for all selected files
								foreach (string file in fileDlg.FileNames)
								{
									handler.OpenFileSelected(_containerService, descriptor, file);

									// Save the selected directory for the next time
									_lastDir = Path.GetDirectoryName(file);
								}
							}
						}
						catch (Exception)
						{
							// We have to ignore exceptions thrown by SingleOrDefault() method
						}
					}
				}
			}
		}

		#endregion
	}
}
